home *** CD-ROM | disk | FTP | other *** search
- Path: news.larc.nasa.gov!amiga-request
- From: amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
- Subject: v91i089: CShell 5.10 - alternative command interface, Part02/06
- Reply-To: umueller@iiic.ethz.ch
- Newsgroups: comp.sources.amiga
- Message-ID: <comp.sources.amiga:v91i089@ab20.larc.nasa.gov>
- References: <comp.sources.amiga:v91i088@ab20.larc.nasa.gov>
- Date: 16 Apr 91 19:34:37 GMT
- Approved: tadguy@uunet.UU.NET (Tad Guy)
- X-Mail-Submissions-To: amiga@uunet.uu.net
- X-Post-Discussions-To: comp.sys.amiga.misc
-
- Submitted-by: umueller@iiic.ethz.ch
- Posting-number: Volume 91, Issue 089
- Archive-name: shells/cshell-5.10/part02
-
- #!/bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 2 (of 6)."
- # Contents: changes.doc csh.doc.ad rawcon.c sub.c
- # Wrapped by tadguy@ab20 on Tue Apr 16 15:34:34 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'changes.doc' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'changes.doc'\"
- else
- echo shar: Extracting \"'changes.doc'\" \(11556 characters\)
- sed "s/^X//" >'changes.doc' <<'END_OF_FILE'
- XNew features to 5.10:
- X- totally rewritten parser, therefore:
- X- local variables, in aliases as well as in batch files
- X- blocks can be formed, redirected, aborted: {e yo;e ho}
- X- $(foo) will insert output of program foo at that point, similar with `foo`
- X- wildcard expansion also done in first arg, e.g. '*' is a legal command line
- X- command lines like '$mydir/$mycommand ram:' now works
- X- aliases/foreach/forline/fornum/source can be redirected as a whole
- X- direct recursion in aliases prevented, 'alias ls "ls -s"' works
- X- additional speedup; twice as fast as 4.xx, four times as fast as c:Execute
- X- '.bra' and '.ket' introduced as dummy commands for script compatibility
- X- 'assign' now yields a list of all assings including late/nonbinding, paths
- X- 'assign -p' does path assigns (like 'c:Assign ... ADD)
- X- 'cat' CR terminated non-CR-termintad files again if not redirected
- X- 'class' can pattern-match now, e.g. 'class sound name="mod.*"'
- X- 'copy' has a larger buffer and checks for ^C more often
- X- 'copy -m' moves files (but not directories yet)
- X- 'dir -p' prints full paths and suppresses titles
- X- 'dir' can separate direcories at the top or bottom
- X- 'dir -z formatstring' is a very powerful formatting feature
- X- 'error' generates a desired return code
- X- 'forline i STDIN' reads args from stdin
- X- 'input' removes leading, trailing and multiple blanks
- X- 'local' and 'unlocal' for generating and deleting local variables
- X- 'man' can handle multiple .doc files, so you can document your own aliases
- X- 'mem' uses , instead of ' and is right adjusted
- X- 'source' can handle multiple line blocks of arbitrary length
- X- 'qsort' can now sort in reverse order
- X- 'rback'/'run' now set the variable '$_newproc' to the # of the new process
- X- $_abbrev can be used to disable abbreviation if internal commands
- X- $_ioerr contains the secondary return code after an error
- X- $_path now contains S: and CSH: in order to run scripts
- X- $_pipe now holds the directory for the temporary pipe files
- X- $_verbose need to be set to special values, now can trace alias calls
- X- @console tells whether stdin or stdout are interactive
- X- @ioerr converts a secondary error number to a string (like 'Why')
- X- @mounted indicates whether a device has been mounted yet or not
- X- @sortnum sorts its arguments numerically
- X- @volume now suppresses ugly system requesters
- X- shift-arrow-up and shift-arrow-down now behave like under AmigaDOS
- X- there is now an editing function that duplicates the last word
- X- csh has a startup option to enable '*' as an alias for '#?' in AmigaDOS
- X- a directory CSH: is proposed for scripts and the doc
- X- concatted lines in source files can be as long as you want
- X- . now stands for current directory, .. for parent
- X- soft and hard links to directories are ignored on wild card expansion
- X
- XBug fixes of 5.10 (in order of severity): bug present since
- X- AmigaDOS residents should work fine now. V37 kickstart required 5.00
- X- 'Wait 5&' as an alias for 'rback Wait 5' now works 5.00
- X- 'rm -r ram:' and 'search -r "" hello' finally do their job 4.00
- X- 'c:execute' works. check the restrictions chapter 3.00
- X- '!!' was broken in the first parser rewrite, fixed now. 5.00
- X- 'return' occasionally didn't skip the whole source file 5.00
- X- '~' now can correctly be used in path names: ~/*.c 5.00
- X- 'Repeat' from menu caused a loop (correct behaviour!) 5.00
- X- 'forline' no longer crashes if the from-file does not exist 4.00
- X- 'set x 1 2;echo hello$x' finally yields 'hello1 2'. 1.00
- X- 'goto' also works if there are '\' in the source file 4.00
- X- command line editing on VT100's was broken. fixed. 5.00
- X- low mem situations now cause a graceful exit instead of a crash 1.00
- X- actions on files with embedded blanks are performed correcty 5.00
- X- 'man' no longer opens garbage files (SnoopDos is hard to cheat) 5.00
- X- 'dir -o' now works (ls -o always did) 5.00
- X- 'dir df0:' with no disk in drive yields correct error message 5.00
- X- 'dir' no longer adds line feeds to invalid date stamps 5.00
- X- 'set _prompt "% "' is now allowed (not only 'set _prompt "%% "') 5.00
- X- 'search -l' no longer does unnecessary line feeds 5.00
- X- '@pickopts' stops picking options at the first non-option 5.00
- X- system requesters are no longer unintentionally disabled 5.00
- X
- XIncompatibilities in 5.10
- X- a stand-alone '.' must be quoted now. check your strhead's and strtail's!
- X- the quick-cd file and the manual (now named csh.doc) should reside in csh:
- X- some builtin aliases and preset function keys have been moved to compat.sh
- X- the functions of shift-arrow-up & down are mapped to esc-arrow-up & down
- X- the path is now searched before auto CD is attempted (mimicking AmigaDOS)
- X- the characters { } @ ( ) should be quoted if you just want to echo them
- X- a redirection error now causes a return code of 20 instead of 1
- X- _verbose now holds numeric values, 'set _verbose yes' won't work anymore
- X- @volume no longer appends a trailing colon to the volume name
- X- an empty string is now passed to external commands as ""
- X- future: a leading '/' and '~' might change meaning towards UNIX
- X
- XNew features to 5.00
- X- read the doc! almost everything's new.
- X
- XBug fixes to 5.00:
- X- recursive wild card expansion does not crash the Amiga 3000 anymore
- X- recursive wild card expansion does not lose memory anymore
- X- now works on AUX:
- X- trying to start a non-object-file now properly prints 'Command Not Found'
- X- automatic sourcing now also works if you already add .sh to the file name
- X- files longer than 999999 bytes no longer misalign 'dir'
- X- exec does not discard the rest of the command line ('exec echo hi;echo ho')
- X- all memory trashing fixed. Thanks to C= for their great debugging tools!
- X- source doesn't forget last character if batchfile was not CR terminated
- X- run & rback also search AmigaDOS path now
- X- division by zero does not crash rpn anymore
- X- temporary pipe files are now written to t: instead of ram:
- X- shift-tab does not cause a lockup anymore
- X- running the shell via aux: no longer crashes the machine
- X- 'history partial' now numbers the lines correctly
- X- strleft, strright and strmid no longer crash on strings > 256 bytes
- X- source with no arguments now prints correct error message
- X- 'input' now cuts down lines longer than 256 bytes instead of crashing
- X- cursor-up no more deletes lines if there's an invalid entry in the history
- X- if history fails, no empty history entry is generated
- X- 'echo "---"' and even 'echo ---' work, but 'echo "-a"' still doesn't
- X- international character sets can be used
- X- 'copy -u' won't copy a file with identical date stamp but in uppercase
- X- 'copy -u' will no longer access low memory
- X- 'echo "echo mem | shell" | shell' now works, not only every second time
- X- starting from workbench now prevented
- X- editing lines longer than 256 bytes is now correctly prevented
- X- word-right cursor movement works correclty with multiple blanks
- X- 'if'-stack will be adjusted when a batch file is exited
- X- relabel occasionally crashed in Syquest drives. should be okay now
- X
- XKnown bugs in 5.00:
- X- under 2.0, doing a 'cat' with no args and pressing return will cause a
- X character to appear at the right border of the window. seems to be a
- X kickstart bug, as it does not happen under older kickstarts.
- X- AmigaDOS 2.0 CLI commands cannot be made resident. They read their command
- X line from stdin. This is definitely a kickstart bug.
- X- guaranteed to crash in extreme low mem situations
- X- command line editing doesn't quite work on a (physical) vt100. OK on VT200
- X- under kick 2.00, fast repetition of ^W crashed. OK under 2.02
- X- 'set x a b;echo hello$x' still outputs only 'a b'
- X
- XIncompatibilities in 5.00:
- X- 'copy -f' now means 'freshen'. Old meaning of -f is now -p (protection)
- X- '~' at the beginning of a file name must now be quoted
- X- '@' is the beginning of an argument should be quoted
- X- 'cat' no longer adds a CR to a non-CR-terminated file
- X- '0' is now 'false'. Example: 'if 0;e hi;else;e ho;endif --> ho
- X- variables with comparision operators inside now cause problems in 'if'
- X- a single '?' will not pattern match, but be passed as a string
- X
- X
- X
- XNew to 4.02A:
- X- Fixed bug that caused loss of memory on exit.
- X- cp now copies protection bits; use -f switch if you want to avoid this.
- X- Added commands: man (and alias manlist), uniq, head, tail, tee.
- X- This doc has been reformatted to work with man.
- X
- XNew to 4.01A:
- X- This version features mostly bug fixes and corrections:
- X * Window title is restored after quitting.
- X * rxrec now answers to the 'bye' message.
- X * rpn can now be redirected and piped; however, this causes
- X some problem (see rpn for info).
- X * resident list now works with ARP 1.3. To recompile source, you must
- X modify include file "libraries/arpbase.h".
- X Change definition of rpn_Usage in struct ResidentProgramNode from LONG
- X to WORD.
- X * pri no more assumes 20 CLI maximum.
- X * you can now split long lines in source files even into more than 2 lines.
- X- Added much info in this doc about source files (chapter XI)
- X- Added copyright notice (see under restrictions).
- X
- XNew to 4.00A:
- X- This version is called 4.00A because it is not 100% compatible with
- X previous versions. We choose to accept this in order to better support
- X the new ARP.library 1.3.
- X- External commands are searched in a different order than before; Shell
- X path is now searched AFTER current directory, AmigaDOS path and C:.
- X- ARP pattern matching has been implemented (in part for line arg expanding,
- X fully for search -w).
- X- Internal changes for various optimizations.
- X- Search command has been improved in several ways.
- X- New commands: basename, tackon.
- X- New options: if -v, resident -d, fornum -v -s, dir -n.
- X- Fixed bugs with dir (some dirs remained locked), foreach -v, htype
- X (blanks were treated as binary), info (for devices > 32M).
- X- rback command now works ok (run, however, doesn't).
- X- Oh, I forgot: it also has an AREXX port... And you don't even have to get
- X AREXX to use it. See new commands rxsend, rxrec
- X
- XNew to 3.03A:
- X- New filter commands fltlower, fltupper.
- X- Added configuration file feature: now if you have a file named S:.login,
- X it will be sourced for every Shell you start.
- X- New option dir -c.
- X- New editing feature: shift-left(right) arrow move cursor to previous(next)
- X word.
- X- Bugs fixed: alias command wasn't listed in help; typing a number as a
- X command was interpreted like 'alias'.
- X
- XNew to 3.02A:
- X- New commands: fornum, forline, strleft, strright, strmid, strlen, exec.
- X- Improved commands: foreach, pri.
- X- New system variable _clinumber.
- X- You can now split long lines in source files (see source for details).
- X- window -q now lists also position of screens/windows, not only dimension.
- X- Since strings are handled directly from Shell with new commands,
- X rpn is now used only for calculations; string commands are gone.
- X However, now RPN is really usable.
- X- Changed rawgets() to fix some problems with function keys, multi-line
- X editing and window resizing; also, fixed bug with ^E.
- X- cat now warns you if it can't find any file matching your pattern.
- X- Now uses DOS packets to get ptr to CLI window; this fixes a bug that
- X caused problems if Shell was run on unactive windows.
- X- Fixed minor bugs (htype printed some more ASCII bytes, some commands
- X returned random values, history didn't print CR's).
- END_OF_FILE
- if test 11556 -ne `wc -c <'changes.doc'`; then
- echo shar: \"'changes.doc'\" unpacked with wrong size!
- fi
- # end of 'changes.doc'
- fi
- if test -f 'csh.doc.ad' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'csh.doc.ad'\"
- else
- echo shar: Extracting \"'csh.doc.ad'\" \(11563 characters\)
- sed "s/^X//" >'csh.doc.ad' <<'END_OF_FILE'
- X If no _except variable exists, any command which fails causes the
- X rest of the line to abort as if an ABORTLINE had been executed. If
- X the _except variable exists, it is of the form:
- X
- X "nnn;commands..."
- X
- X where nnn is some value representing the minimum return code
- X required to cause an error. Whenever a command returns a code
- X which is larger or equal to nnn, the commands in _except are
- X executed before anything. WHEN _except EXISTS, THE COMMAND LINE
- X DOES NOT ABORT AUTOMATICALLY. Thus, if you want the current line
- X being executed to be aborted, the last command in _except should be
- X an "abortline".
- X
- X Exception handling is disabled while in the exception handling
- X routine (thus you can't get into any infinite loops this way).
- X
- X Thus if _except = ";", return codes are completely ignored.
- X
- X Example:
- X
- X set _except "20;abortline"
- X
- X
- XXII. EXAMPLE SOURCE FILES
- X-------------------------
- X
- XIf from a CLI or the startup-script you say 'SHELL filename', that file is
- Xsourced first.
- X
- X### compat.sh ###
- X
- X# this makes sure that your old abbreviations don't call new commands
- X
- Xalias as aset
- Xalias cl close
- Xalias g goto
- Xalias h help
- Xalias he help
- Xalias m md
- Xalias q quit
- Xalias re rename
- Xalias w window
- X
- Xalias kr "rm -r ram:* >NIL:
- X
- X### End of compat.sh ###
- X
- X
- XMoreover, if you have a file called S:.login, it will be sourced for every
- XShell you run. This is useful for aliases and setting that you want in ALL
- XShells.
- X
- X
- X### Example S:.login ###
- X
- XHere is an example .login file:
- X
- Xset F5 "cdir WORK:"^M
- Xset f9 "ed s:login.sh"^M
- Xset F9 "ed df0:s/startup-sequence"^M
- X
- Xalias toram "%q foreach i ( $q ) \"cp -r $i: ram:$i >NIL:;assign $i: ram:$i
- Xalias ramop "md RAM:op; assign OP: ram:op
- Xalias noop "assign OP: ; rm -r ram:op
- Xalias newop "rm -r OP:*
- Xalias dc "dfc df0: to df1:
- Xalias go "%q assign WORK: Boot:$q; cd WORK:; source startme.sh
- Xalias get "%q cp $q RAM: >NIL:
- Xalias filter "%a%b%c exec $b \\<$a \\>$c
- X # reads $a, filters it with $b and writes result to $c
- X
- Xalias rm "%q \\rm @confirm( Remove $q )
- X
- X#alias rm "%a set f @pickargs( $a );set opts @pickargs( $a );\
- X# e -n OK to delete @words( @files( $f ) ) file(s) and @words( @dirs( $f ) )\
- X# directories\"? \";input b;if $b = y;\\rm $opts $f;endif
- X# # for the anxious among us: confirmed rm
- X
- Xset _prompt "%c%p> "
- X # this puts the path highlighted in the prompt
- X
- X# this one puts cli number, free mem, date and time in title bar
- Xset _titlebar "Shell %n Mem %m Date %d Time %t
- X
- X# This file will be sourced for every Shell you start
- X
- X### End of example .login ###
- X
- X****************************************************************************
- X
- XIf you are a CLI user, your startup-sequence may be as simple as:
- X
- X C:csh S:startup.sh
- X
- XHere's a startup code:
- X
- X### Example S:startup.sh ###
- X
- Xwind -l # if you are on a PAL machine, or use overscan
- X # note that commands may be abbreviated (wind=window)
- X
- Xassign LC: Stuff:c INCLUDE: Stuff:include LIB: Boot:lib QUAD: RAM:
- X
- Xrback C:FaccII; sleep 1
- X # after spawning a process, it is always better to allow it
- X # to load the command, to avoid excessive drive head movement
- X
- Xresident -d blink lc1 lc2 >NIL: #defer loading
- X
- XC:PopCli 300 C:Newcli #using full pathname loads faster
- XC:FF -1 Siesta.font >NIL:
- XC:Patch_1 >NIL:
- Xstack 8000 # lc1 and lc2 need this
- X
- Xsource S:setdate.sh # this is listed next
- X
- X### End of example startup.sh ###
- X
- X****************************************************************************
- X
- XThe following is an example source file to set date and time; it may be
- Xused at startup if you don't have an internal clock.
- X
- X### setdate.sh ###
- X
- Xopen CON:200/100/440/80/SetDate write 1
- Xecho >.1 -n "Current date is "
- Xdate >.1
- Xecho >.1 -n "Please enter date: "
- Xinput <.1 d
- Xclose 1
- Xstrlen len $d
- Xif $len > 1 ; date $d ; endif
- Xecho -n "New date: " ; date
- X
- X### End of setdate.sh ###
- X
- X***************************************************************************
- X
- XNext comes a makefile that needs no Make program: may be executed from
- XShell directely!!!
- X
- X### make.sh ###
- X
- Xif -t Shell.syms Shell.h; cc +HShell.syms Shell.h; rm shell.o; endif
- Xif -t RAM:Shell.syms Shell.syms; cp -d Shell.syms RAM:; endif
- X
- Xforeach i ( main comm1 comm2 comm3 execom globals rawconsole run set \
- X sub ) "if -t $i.o $i.c; echo Compile $i...;cc +IRAM:shell.syms $i.c; endif"
- X
- X# we used line continuation for better visibility. this is not necessary,
- X# you can type it all in one line. no more limit of 256 bytes per line
- X
- Xif -t Shell run.o main.o comm1.o comm2.o comm3.o execom.o \
- Xset.o sub.o globals.o rawconsole.o
- X ln +q -m -o Shell run.o main.o comm1.o comm2.o comm3.o\
- X execom.o set.o sub.o globals.o rawconsole.o -la -lc
- Xendif
- X
- X### End of make.sh ###
- X
- X
- XXIII. Default Values
- X--------------------
- X
- XTo make things easier, some aliases are predefined whenever you start a
- Xnew Shell. These are:
- X
- X CLS
- X Simply clear the screen.
- X
- X CDIR
- X Use "cdir directory" to clear the screen, set CD to directory,
- X and list it.
- X
- X EXIT
- X Leave Shell and exit CLI.
- X
- X FG
- X Runs current shell in foreground, this means priority 1.
- X
- X KR
- X Used to delete everything on RAM:. This one is gone, if you still
- X want it, you'll have to put it in your s:.login
- X
- X LP
- X List to printer one or more files.
- X
- X MANLIST
- X Display a list of possible arguments to man. You can pipe this to
- X qsort to get a sorted output.
- X
- X NICE
- X Sets this shell to priority -1.
- X
- XMoreover, many variables have default values, and many function keys are
- Xpredefined. You can use set command to determine all of these.
- X
- XXIV. Object oriented features
- X------------------------------
- X
- X CLASSES OF FILES
- X
- X You can define a class of files using several 'class' commands.
- X Here a simple example:
- X
- X class picture suff=.pic suff=.iff suff=.ilbm
- X class anim suff=.anim
- X
- X From now on, everything with the suffix .pic, .iff or .ilbm will
- X be identified as a picture. Please note that there may be no blanks
- X between the names and the '=', and that blanks inside the names
- X must be put in quotes. So these are the ways to identify a file:
- X
- X suff=.doc True if the suffix of the file is .doc
- X name=readme True if the file is "readme"
- X name="mod.*" True if the name starts with 'mod.'
- X offs=14,DC..C4FD True if the bytes starting at $14 are $DC,
- X anything, $C4, $FD (all numbers hexadecimal!).
- X Each pair of dots means one byte ignored.
- X chars True if 90% of the bytes in the file are 32..127
- X or 9..13
- X default Always true, used to define the default type
- X
- X Note that only the first character is examined, so 's' = 'suff'.
- X One class can be identified by more than one 'class' statement.
- X They are looked at in the same sequence they were entered. So to
- X make sure that an zoo archive misnamed as .lzh is identified
- X correctly, use the following 'class' statements:
- X
- X class zoo offs=14,DCA7C4FD
- X class lzh offs=2,2D6C68..2D
- X class zoo suff=.zoo
- X class lzh suff=.lzh
- X
- X Moreover, there is a builtin class 'dir', which means directory.
- X Now we know many file types. But what to do with them? This is
- X where we define 'actions'.
- X
- X ACTIONS ON CLASSES
- X
- X There may be one or more 'class' commands that define what actions
- X need to be taken in various cases for that specific class:
- X
- X class zoo actions view="zoo -list" extr="zoo -extract"
- X class lzh actions view="lz l" extr="lz e"
- X
- X Whenever somebody tries to 'view' a test.zoo, the command
- X 'zoo -list test.zoo' will be issued, but if he tries to
- X view test.lzh, then 'lz l test.lzh' will be executed. Note
- X that any command supplied here goes through the normal csh
- X parser, so AmigaDOS and csh paths will be searched. Aliases
- X with arguments are allowed here, too, so whatever the user
- X typed will be stored in the variable after the '%'.
- X
- X How do I tell a file that I want to 'view' it? There comes the
- X second command used for object oriented features:
- X
- X action view test.zoo
- X
- X will first identify the type of that file and then apply, if
- X possible, the 'view' action to it. Of course, this works best
- X inside an alias: alias v "action view" will define a v-command
- X that views all types of files known to cshell. Similarly, you
- X can define alias xtr "action extr" and use this command to
- X extract files from any type of archive.
- X There is one action that will be sent to every file that you
- X try to start but is not executable. This action is 'exec'.
- X Assume you have defined the class 'picture', then after
- X
- X class picture actions view=Mostra exec=Mostra
- X
- X you can display a picture using Mostra by just typing its name.
- X More builtin actions like 'rm' and 'dir' may be implemented,
- X so don't use command names for action names.
- X
- X The batch file class.sh defines a few useful classes.
- X
- X
- X
- XXV. Keymaps
- X---------------
- X
- X You define a keymap as a collection of key/function pairs. Both
- X are given as numbers. There can be several keymaps which activate
- X each other, but at first we only edit keymap 0, which is active
- X at the beginning. All keys you define will eventually overwrite
- X the old definitions in an existing keymap. Everithing marked with
- X a (*) is not yet implemented.
- X
- X KEYCODES
- X
- X 1..255 The corresponding ASCII character
- X 256 Up Arrow
- X 257 Down Arrow
- X 258 Right Arrow
- X 259 Left Arrow
- X 260 Help
- X 261..270 F1..F10 (unshifted)
- X
- X
- X Modifiers (add them to the key code)
- X
- X 512 SHIFT (only necessary for arrows and fkeys)
- X 1024 ESC (was pressed & released before this key)
- X
- X EDITFUNCTIONS
- X
- X - Movement Move cursor...
- X 0 CursLeft 1 left
- X 1 CursRight 1 right
- X 2 WordLeft 1 word left
- X 3 WordRight 1 word right
- X 4 BegOfLine to beginning of line
- X 5 EndOfLine to end of line
- X
- X - Deleting Delete...
- X 10 Backspace char left from cursor
- X 11 Delete char right from cursor
- X 12 BkspcWord word left from cursor
- X 13 DelWord word right from cursor
- X 14 DeleteToSOL to start of line
- X 15 DeleteToEOL to end of line
- X 16 DeleteLine whole line
- X
- X - History insert
- X 20 Back Move one line back in history
- X 21 Forward Move one line forward in history
- X 22 Beg Move to first line in history
- X 23 End Move to last line in history
- X 24 Complete History retrieve like '!'
- X 25 Exec Execute history line & bring up next
- X 26 Tail Insert previous line except first word
- X 27 Bottom Go below last history command
- X 28 DupWord Duplicates the last word on this line
- X
- X - Completion
- X 30 Normal Insert first matching file (or cycle)
- X 31 Partial Insert substring of all matching files
- X 32 All Insert all matching files
- X 33 Directory Find dir in quick cd list
- X 34 LastCD Insert last current directory
- X
- X - Special
- X 40 Insert Toggle Insert/Overwrite
- X 41 Quit Silently perform 'quit'
- X 42 Help Silently perform 'help'
- X 43 Refresh Redraw current line
- X 44 Execute Execute current line
- X 45 Leave Edit new line, store this in hist
- X 46 EOF Terminate shell
- X 47 NOP Do nothing
- X 48 Echo^O Echoes a ^O
- X 49 Beep Echoes a ^G
- X
- X - Other
- X 50 Fkey Execute command associated to last fkey
- X 51 Menu Execute command associated to last menu
- X 52 Undo Undoes last edit
- X 53 Repeat Repeats last function
- X
- X
- X Command types
- X
- X 0 +x Editing function x, see above descriptions
- X 512 +x Setmap x, x=0..7
- X 1024+x Insert key x, x=1..255
- X 1536+x Macro x x=1..15 (*)
- X 2048+x String x x=1..15 (*)
- END_OF_FILE
- if test 11563 -ne `wc -c <'csh.doc.ad'`; then
- echo shar: \"'csh.doc.ad'\" unpacked with wrong size!
- fi
- # end of 'csh.doc.ad'
- fi
- if test -f 'rawcon.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'rawcon.c'\"
- else
- echo shar: Extracting \"'rawcon.c'\" \(18348 characters\)
- sed "s/^X//" >'rawcon.c' <<'END_OF_FILE'
- X/*
- X * rawcon.c
- X *
- X * Shell 2.07M 17-Jun-87
- X * console handling, command line editing support for Shell
- X * using new console packets from 1.2.
- X * Written by Steve Drew. (c) 14-Oct-86.
- X * 16-Dec-86 Slight mods to rawgets() for Disktrashing.
- X *
- X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
- X * Version 5.00L by Urban Mueller 17-Feb-91
- X *
- X */
- X
- X#include "shell.h"
- X
- Xstatic int myget( void );
- Xstatic void myunget(int c);
- Xstatic void setrawcon( long flag, int ievent );
- Xstatic int get_seq( long *param );
- Xstatic int bkspcword( int i, int max, int cnt );
- X
- X
- X#if RAW_CONSOLE
- X
- Xstatic char *tyahdptr, *lasttya;
- Xstatic int tabctr, qcdctr, unget;
- X
- X#define SETRAW setrawcon(-1L,1);
- X#define SETCON setrawcon( 0L,1);
- X
- Xint w_width;
- Xextern char *MenuCommand[MAXMENUS][MAXITEMS];
- X
- X#define CTRL -64
- X#define SHIFT 512
- X#define ESC 1024
- X
- X#define CUP 256
- X#define CDN 257
- X#define CRT 258
- X#define CLT 259
- X#define TAB 9
- X
- Xstatic int Curmap;
- Xstatic USHORT *Keymap[8];
- Xstatic USHORT DefKeymap0[]={
- X CLT, 0, /* CursLt = Move.Left */
- X CRT, 1, /* CursRt = Move.Right */
- X SHIFT+CLT, 2, /* SCursLt= Move.WordL */
- X SHIFT+CRT, 3, /* SCursRt= Move.WordR */
- X ESC+CLT, 4, /* ESC-CLt= Move.SOL */
- X ESC+CRT, 5, /* ESC-CRt= Move.EOL */
- X CTRL+'A', 4, /* ^A = Move.SOL */
- X CTRL+'E', 5, /* ^E = Move.EOL */
- X CTRL+'Z', 4, /* ^Z = Move.SOL */
- X 8, 10, /* BackSp = Del.BackSp */
- X 127, 11, /* Delete = Del.Delete */
- X ESC+ 8, 12, /* ESC-BkS= Del.WordL */
- X ESC+127, 13, /* ESC-Del= Del.WordR */
- X CTRL+'W', 12, /* ^W = Del.WordL */
- X CTRL+'B', 14, /* ^B = Del.SOL */
- X CTRL+'K', 15, /* ^K = Del.EOL */
- X ESC+'x',513, /* ESC-x = Setmap 1 */
- X ESC+'d', 16, /* ESC-d = Del.Line */
- X CTRL+'X', 16, /* ^X = Del.Line */
- X CUP, 20, /* CursUp = Hist.Back */
- X CDN, 21, /* CursDn = Hist.Forw */
- X ESC+CUP, 22, /* ECursUp= Hist.Beg */
- X ESC+CDN, 23, /* ECursDn= Hist.End */
- X SHIFT+CUP, 24, /* SCursUp= Hist.Compl */
- X ESC+CUP, 24, /* ESC-! = Hist.Compl */
- X ESC+ 13, 25, /* ESC-Ret= Hist.Exec */
- X CTRL+'T', 26, /* ^T = Hist.Tail */
- X SHIFT+CDN, 27, /* SCursDn= Hist.Clr */
- X CTRL+'P', 28, /* ^P = Hist.DupWrd*/
- X TAB, 30, /* Tab = Comp.Norm */
- X SHIFT+TAB, 31, /* STab = Comp.Part */
- X ESC+TAB, 32, /* ESC-TAB= Comp.All */
- X ESC+'c', 33, /* ESC-c = Comp.CD */
- X ESC+'~', 34, /* ESC-~ = Comp.LastCD*/
- X ESC+'i', 40, /* ESC-i = Spec.Insert*/
- X CTRL+'L', 43, /* ^L = Spec.Refr */
- X 10, 44, /* Enter = Spec.Accept*/
- X 13, 44, /* ^Enter = Spec.Accept*/
- X CTRL+'N', 45, /* ^N = Spec.Next */
- X CTRL+'O', 48, /* ^O = Spec.EchoO */
- X CTRL+'\\', 46, /* ^\ = Spec.EOF */
- X 260, 42, /* Help = Misc.Help */
- X 271, 51, /* Menu = Menu */
- X CTRL+'U', 52, /* Undo = Spec.Undo */
- X CTRL+'R', 53, /* Repeat = Spec.Repeat*/
- X 0, 0
- X};
- X
- Xstatic USHORT DefKeymap1[]={
- X 8, 14,
- X 127, 15
- X};
- X
- Xstatic char *Line, *Prompt;
- Xstatic int Pl;
- Xstatic char LastDir[128];
- X
- Xvoid
- Xinitmap(void)
- X{
- X if( !Keymap[0] )
- X Keymap[0]=DefKeymap0, Keymap[1]=DefKeymap1;
- X}
- X
- Xchar *
- Xrawgets( char line[], char prompt[] )
- X{
- X static int inslen, lastrecall=-1;
- X static int lastfn, lastkey;
- X
- X int n, pl, max, i, c, key, fn, cnt;
- X USHORT *p;
- X char *s, *ps, typeahd[256], undo[256], *src, tmp;
- X int savn, insert=1, recall, undo_i=0, undo_max=0;
- X struct HIST *hist;
- X char **eav=NULL, *ret, fake;
- X int eac, eactr=0;
- X long param[10], *par;
- X
- X typeahd[0]=0;
- X tyahdptr=lasttya=typeahd;
- X
- X newwidth();
- X
- X if ( o_noraw || !IsInteractive(Input()) ) {
- X if( IsInteractive(Input())) {
- X printf("%s",prompt);
- X fflush(stdout);
- X }
- X return(gets(line));
- X }
- X
- X if (WaitForChar((long)Input(), 100L) || /* don't switch to 1L ...*/
- X CHARSWAIT(stdin)) { /* else causes read err's*/
- X gets(line);
- X return(line);
- X }
- X
- X SETRAW;
- Xbegin:
- X printf("\015%s\033[6n",prompt);
- X fake= savn = pl = n = 0;
- X tyahdptr = typeahd;
- X
- X while( (typeahd[n]=getchar()) != 'R') {
- X if (typeahd[n] == 155) savn = n;
- X if (typeahd[n] == 27 && getchar()=='[')
- X typeahd[n] =155, savn=n;
- X n++;
- X }
- X /* typeahd now contains possible type a head chars
- X followed by <CSI> cursor position report. */
- X
- X typeahd[savn] = '\0';
- X if (typeahd[n-2] != ';') pl = (typeahd[n-2] -'0') * 10;
- X pl += typeahd[n-1] - 49;
- X ps = line + pl;
- X line[max = i = pl] = '\0';
- X
- X Line=line; Prompt=prompt; Pl=pl;
- X
- X if (s = get_var (LEVEL_SET, "_insert")) insert = atoi(s) ? 1 : 0;
- X
- X if( (recall=lastrecall)>=0 ) {
- X lastrecall=-1;
- X goto recallh;
- X }
- X
- X while( (c=myget()) != -1) {
- X int esc=0;
- X key=-1;
- X if( c==27 ) {
- X esc=ESC;
- X if((c=myget())=='[')
- X c=155,esc=0;
- X }
- X switch(c) {
- X case 155:
- X switch(c=myget()) {
- X case 'A': key=256; break; /* CursUp */
- X case 'B': key=257; break; /* CursDn */
- X case 'C': key=258; break; /* CursRt */
- X case 'D': key=259; break; /* CursLt */
- X case 'T': key=256+SHIFT; break; /* SCursUp */
- X case 'S': key=257+SHIFT; break; /* SCursDn */
- X case ' ':
- X switch( myget() ) {
- X case '@': key=258+SHIFT; break; /* SCursRt */
- X case 'A': key=259+SHIFT; break; /* SCursLt */
- X }
- X break;
- X case 'Z': key= 9+SHIFT; break; /* STab */
- X case '?': key= 260; myget(); break; /* Help */
- X default :
- X myunget(c);
- X par=param;
- X do {
- X for( *par=0; (c=myget())>='0' && c<='9'; )
- X *par=10* *par + c-'0';
- X par++;
- X } while( c==';' );
- X if( c=='~' ) {
- X key=param[0]+261;
- X if( key>270 ) key+=SHIFT-10;
- X }
- X if( c=='|' ) key=271;
- X } break;
- X default: key=c; break;
- X }
- X key+=esc;
- X
- X for( fn=-1, p=Keymap[Curmap]; *p; p+=2 )
- X if( *p==key )
- X { fn=p[1]; break; }
- X if( fn==-1 && key>=261 && key<=270 || key>=261+SHIFT && key<=270+SHIFT )
- X fn=50;
- X
- X if( fn!=52 && !*lasttya) {
- X memcpy( undo+pl, line+pl, max-pl );
- X undo_i=i; undo_max=max;
- X }
- X
- X switch( fn/512 ) {
- X case 1:
- X fn&=511;
- X if( fn<8 && Keymap[fn] ) Curmap=fn;
- X fn=-2;
- X break;
- X case 2:
- X key=fn&511, fn=-1;
- X break;
- X }
- X
- X if( fn!=-2 )
- X Curmap=0;
- X
- X if( fn!=53 && !*lasttya )
- X lastfn=fn, lastkey=key;
- X
- Xdofn:
- X switch( fn ) {
- X case -2:
- X break;
- X
- X case 0: /* cursor left */
- X if (i > pl)
- X i--, printf("\033[D");
- X break;
- X case 1: /* cursor right */
- X if (i < max)
- X i++, printf("\033[C");
- X break;
- X case 2: /* word left */
- X for (cnt=0; i>pl && line[i-1] == ' '; cnt++,i--);
- X for ( ; i>pl && line[i-1] != ' '; cnt++,i--);
- X if( cnt ) printf("\033[%dD",cnt);
- X break;
- X case 3: /* word right */
- X for( cnt=0; i<max && line[i] != ' '; i++,cnt++) ;
- X for( ; i<max && line[i] == ' '; i++,cnt++) ;
- X if( cnt ) printf("\033[%dC",cnt);
- X break;
- X case 4: /* beg of line */
- X if (i>pl) printf("\033[%dD",i-pl);
- X i = pl;
- X break;
- X case 5: /* end of line */
- X if (i!=max) printf("\033[%dC",max - i);
- X i = max;
- X break;
- X
- X case 10: /* backspace */
- X if (i > pl) {
- X i--;
- X printf("\010");
- X } else break;
- X case 11: /* delete */
- X if (i < max) {
- X int j,t,l = 0;
- X memmove(&line[i],&line[i+1],max-i);
- X --max;
- X printf("\033[P");
- X j = w_width - i % w_width - 1; /* amount to end */
- X t = max/w_width - i/w_width; /* no of lines */
- X for(n = 0; n < t; n++) {
- X l += j; /* # of char moved*/
- X if (j) printf("\033[%dC",j);/* goto eol */
- X printf("%c\033[P",line[w_width*(i/w_width+n+1)-1]);
- X j = w_width-1;
- X }
- X if (t)
- X printf("\033[%dD",l+t); /* get back */
- X }
- X break;
- X case 12: /* bkspc word */
- X cnt= bkspcword(i,max,-1);
- X max-=cnt; i-=cnt;
- X break;
- X case 13:
- X for( cnt=0; i<max && line[i]!=' '; i++,cnt++ ) ;
- X for( ; i<max && line[i]==' '; i++,cnt++ ) ;
- X if ( cnt ) printf("\033[%dC",cnt);
- X cnt=bkspcword(i,max,cnt);
- X i-=cnt; max-=cnt;
- X break;
- X case 14:
- X cnt=bkspcword(i,max,i-pl);
- X i-=cnt; max-=cnt;
- X break;
- X case 16: /* delete line */
- X if (i>pl) printf("\033[%dD",i-pl);
- X i = pl;
- X case 15: /* delete to EOL */
- X printf("\033[J");
- X max = i;
- X line[i] = '\0';
- X break;
- X
- X
- X case 20: /* history up */
- X ++recall;
- X case 21: /* history down */
- Xrecallh:
- X line[pl] = '\0';
- X if (recall >= 0 || fn==20) {
- X if ( fn==21 ) --recall;
- X n=recall;
- X if (recall >= 0) {
- X for(hist = H_head; hist && n--;
- X hist = hist->next);
- X if (hist) strcpy(&line[pl],hist->line);
- X else recall = H_len;
- X }
- X }
- X if (i != pl)
- X printf("\033[%dD",i-pl);
- X printf("\033[J%s",ps);
- X i = max = strlen(ps) + pl;
- X break;
- X case 22: /* beg of hist */
- X recall = H_len-1;
- X case 23: /* end of hist */
- X line[pl] = '\0';
- X if (fn == 23) {
- X recall = 0;
- X if (H_head) strcpy(&line[pl], H_head->line);
- X } else if (H_tail)
- X strcpy(&line[pl], H_tail->line);
- X printf("\015\033[J%s%s", prompt, ps);
- X i = max = strlen(ps) + pl;
- X break;
- X case 24: /* complete hist */
- X line[max]=0;
- X if( s=get_history(&line[pl-1],0 )) {
- X if (i>pl) printf("\033[%dD\033[J",i-pl);
- X line[i=max=pl]=0;
- X strncpy(typeahd,s,256);
- X tyahdptr=typeahd;
- X }
- X break;
- X case 25: /* exec hist */
- X lastrecall= recall;
- X goto done;
- X case 26: /* tail of prev */
- X if( H_head && (s=H_head->line) && (s=index(s,' ')) )
- X tyahdptr=s;
- X break;
- X case 27: /* botton */
- X recall=-1;
- X goto recallh;
- X case 28: /* duplicate word */
- X for(s=line+i; s>ps && *(s-1)==' '; --s ) ;
- X tmp=*s; *s=0;
- X if( !(src=rindex(ps,' '))) src="";
- X strcpy(tyahdptr=typeahd,src);
- X *s=tmp;
- X break;
- X
- X case 30: /* complete */
- X case 31:
- X case 32:
- X case 33: {
- X static int lastcompl;
- X int j, k, n, e, cnt, len, radlen;
- X char *name, *q, abbrev;
- X
- X abbrev= fn==31;
- Xcomplete:
- X tyahdptr="";
- X if( tabctr!=0 ) {
- X char *dest=typeahd, *lcd;
- X
- X lastcompl=fn;
- X for( cnt=0; i<max && line[i]!=' '; ++i, ++cnt ) ;
- X if(cnt) printf("\033[%dC",cnt);
- X for( e=i, j=i-1, cnt=0; j>=pl && line[j]!=' ' && line[j]!='<' &&
- X line[j]!='>' && line[j]!=';' ; --j ) cnt++;
- X ++j;
- X
- X if( line[j]=='~' && (lcd=get_var(LEVEL_SET,v_lcd))) {
- X strcpy(dest,lcd);
- X dest+=strlen(dest);
- X j++;
- X }
- X memcpy(dest,&line[j],e-j);
- X dest+=e-j;
- X if( fn!=33 )
- X *dest++='*';
- X *dest=0;
- X if( eav ) free_expand( eav ), eav=NULL;
- X breakreset();
- X tabctr=1;
- X if( fn==33 ) {
- X strncpy(LastDir,typeahd,128);
- X if( !quick_cd( name=typeahd+128, LastDir, 0))
- X { putchar(7); break; }
- X } else {
- X eav =expand(typeahd,&eac);
- X if( eac==0 ) { putchar(7); break; }
- X QuickSort(eav, eac);
- X if( fn==30 )
- X name=eav[ eactr=0 ];
- X else
- X name=compile_av(eav,0,eac,' ',1), tabctr=0;
- X }
- X inslen=cnt;
- X } else {
- X abbrev=0, tabctr=1;
- X if( lastcompl==33 ) {
- X quick_cd( name=typeahd+128, LastDir, 1);
- X } else {
- X if( !eac ) break;
- X name=eav[eactr=++eactr % eac];
- X }
- X }
- X len=bkspcword(i,max,inslen);
- X i-=len; max-=len;
- X if( abbrev && eac>1) {
- X strcpy( typeahd, eav[0] );
- X radlen= 9999;
- X for( k=0; k<eac; k++ ) {
- X if ( (n=strlen(eav[k])) < radlen ) radlen=n;
- X for( n=0; n<radlen && eav[0][n]==eav[k][n]; n++ ) ;
- X if ( n<radlen ) radlen=n;
- X }
- X typeahd[radlen]=0;
- X eactr--;
- X } else {
- X if( lastcompl==32 ) {
- X strncpy( typeahd,name,250 );
- X name[250]=0;
- X } else {
- X strcpy(typeahd,(q=index( name, ' ' )) ? "\"" : "" );
- X strcat(typeahd,name);
- X if( q ) strcat(typeahd,"\"");
- X if( lastcompl==33 || isdir(name) )
- X appendslash( typeahd );
- X else
- X strcat( typeahd, " " );
- X }
- X }
- X tyahdptr=typeahd;
- X inslen=strlen(typeahd);
- X }
- X break;
- X case 34:
- X strncpy(typeahd,get_var( LEVEL_SET, v_lcd ),230);
- X appendslash(tyahdptr=typeahd);
- X break;
- X
- X case 40: /* ins/ovr */
- X insert ^= 1;
- X break;
- X case 41: /* quit */
- X strcpy(ps,"quit");
- X goto done;
- X case 42: /* help */
- X strcpy(ps,"help");
- X goto done;
- X case 43: /* refresh */
- X if ((n = i/w_width)) printf("\033[%dF",n);
- X printf("\015\033[J%s%s",prompt,ps);
- X i = max;
- X break;
- X case 44:
- X line[max] = '\0';
- Xdone: printf("\033[%dC\n",max - i);
- X strcpy(line, ps);
- X ret=line;
- X if( fake ) goto begin;
- X goto exit;
- X case 45: /* leave */
- X line[max] = '\0';
- X add_history( ps );
- X fake=1;
- X goto done;
- X case 46: /* EOF */
- X ret=NULL;
- X goto exit;
- X case 47:
- X break;
- X case 48:
- X printf("\017");
- X break;
- X case 49:
- X printf("\07");
- X break;
- X
- X case 50: {
- X char fkeys[8];
- X sprintf(fkeys,"%c%d",param[0]>=10?'F':'f',param[0]%10+1);
- X if (s = get_var(LEVEL_SET, fkeys)) {
- X tyahdptr = strcpy(typeahd,s);
- X a0tospace( tyahdptr );
- X }
- X break;
- X }
- X case 51: {
- X int class=param[0], code=param[2];
- X if( class==10 ) {
- X int num=MENUNUM( code ), item=ITEMNUM( code );
- X tyahdptr="";
- X if( num>=0 && num<MAXMENUS && item>=0 && item<=MAXITEMS )
- X tyahdptr=MenuCommand[num][item];
- X }
- X if( class==11 ) {
- X strcpy(ps,"quit");
- X goto done;
- X }
- X }
- X case 52: {
- X int t;
- X
- X if ((n = i/w_width)) printf("\033[%dF",n);
- X swapmem( undo+pl, line+pl, MAX( max, undo_max)-pl );
- X t=max; max=undo_max; undo_max=t;
- X t=i; i =undo_i; undo_i =t;
- X line[max]=0;
- X printf("\015\033[J%s%s",prompt,ps);
- X if( i<max ) printf("\033[%dD",max-i);
- X }
- X break;
- X case 53:
- X fn=lastfn; key=lastkey;
- X goto dofn;
- X
- X default:
- X key&=255;
- X if (key == 9) key = 32;
- X if (key > 31 && (insert?max:i) < 256) {
- X if (i < max && insert) {
- X int j,t,l = 0;
- X memmove(&line[i+1], &line[i], max - i);
- X printf("\033[@%c",key);
- X t = max/w_width - i/w_width;
- X j = w_width - i % w_width - 1;
- X for(n = 0; n < t; n++) {
- X l += j;
- X if (j) printf("\033[%dC",j);
- X printf("\033[@%c",line[w_width*(i/w_width+n+1)]);
- X j = w_width-1;
- X }
- X if (t) printf("\033[%dD",l + t);
- X ++max;
- X }
- X else {
- X if(i == pl && max == i) printf("\015%s%s",prompt,ps);
- X putchar(key);
- X }
- X line[i++] = key;
- X if (max < i) max = i;
- X line[max] = '\0';
- X }
- X }
- X }
- X ret=NULL;
- Xexit:
- X newwidth();
- X if( eav ) free_expand(eav);
- X SETCON;
- X return ret;
- X}
- X
- Xint
- Xbkspcword( int i, int max, int cnt )
- X{
- X int o=i;
- X
- X if( !cnt ) return 0;
- X
- X if( cnt==-1 ) {
- X cnt=0;
- X while( i>Pl && Line[i-1]==' ' ) i--, cnt++;
- X while( i>Pl && Line[i-1]!=' ' ) i--, cnt++;
- X } else
- X i-=cnt;
- X
- X if( cnt ) printf("\033[%dD",cnt);
- X memmove( Line+i, Line+o, max-o );
- X memset ( Line+max-cnt, ' ', cnt );
- X
- X printf("%s",Line+i);
- X
- X if( max-i ) printf("\033[%dD", max-i );
- X fflush(stdout);
- X Line[max-=cnt]=0;
- X
- X return cnt;
- X}
- X
- Xvoid
- Xsetrawcon( long flag, int ievent ) /* -1L=RAW:, 0L=CON: */
- X{
- X static char menuon, button;
- X long packargs[8];
- X
- X if( !o_nowindow && ievent && flag==0 && menuon)
- X printf("\033[10}"), menuon=0;
- X
- X packargs[0]=flag;
- X SendPacket(994L, packargs, (void *)Myprocess->pr_ConsoleTask);
- X
- X if( !o_nowindow && ievent && flag==-1 ) {
- X if( !menuon )
- X printf("\033[10{"), menuon=1;
- X if( !button )
- X printf("\033[11{"), button=1;
- X }
- X fflush(stdout);
- X}
- X
- X
- X
- Xstatic int row, height, cnt, noquick=1;
- Xstatic char scrollstr[10];
- X
- Xextern BPTR OldCin;
- X
- Xstatic int FromTee;
- X
- Xvoid
- Xprepscroll( int fromtee )
- X{
- X BPTR truecin=0;
- X long param[8];
- X
- X row=height=0;
- X FromTee=fromtee;
- X
- X if(( noquick=!o_scroll ||o_noraw || o_nofastscr ))
- X return;
- X if(( noquick=!IsInteractive(Output()) && !fromtee ))
- X return;
- X if( !IsInteractive(Input())) {
- X truecin=Myprocess->pr_CIS;
- X
- X if( noquick=!IsInteractive(OldCin) )
- X return;
- X
- X Myprocess->pr_CIS = DEVTAB(stdin) = OldCin;
- X }
- X
- X if( !CHARSWAIT(stdin) ) {
- X SETRAW;
- X fprintf(fromtee?stderr:stdout,"\033[ q");
- X get_seq( param );
- X height=param[2];
- X while( getchar()!='r') ;
- X
- X fprintf(fromtee?stderr:stdout,"\033[6n");
- X get_seq( param );
- X row=param[0];
- X
- X SETCON;
- X
- X cnt= height-row+1;
- X noquick= height<o_minrows;
- X }
- X
- X sprintf(scrollstr,"\033[%cS\033[%cA", o_scroll+'0', o_scroll+'0');
- X
- X if( truecin )
- X Myprocess->pr_CIS = DEVTAB(stdin) = truecin;
- X}
- X
- Xstatic int
- Xget_seq( long *param )
- X{
- X int c;
- X
- X while( (c=getchar())!=155 ) ;
- X do {
- X *param=0;
- X while( (c=getchar())>='0' && c<='9' )
- X *param=10* *param + c-'0';
- X param++;
- X } while( c==';' );
- X
- X return c;
- X}
- X
- X
- Xvoid
- Xquickscroll( void )
- X{
- X if( noquick ) return;
- X
- X if( --cnt<=0 ) {
- X cnt=o_scroll;
- X fprintf( FromTee ? stderr : stdout, "%s",scrollstr);
- X }
- X}
- X
- Xint
- Xdo_keymap( void )
- X{
- X int i, n, len;
- X USHORT *tmp, *put, *get, *map;
- X char *ind;
- X
- X n=myatoi(av[1],0,7);
- X if( atoierr ) return 20;
- X
- X map=Keymap[n]; len=0;
- X if( map )
- X for( len=0; map[2*len]; len++ ) ;
- X
- X put=tmp=salloc((len+ac)*2*sizeof(USHORT));
- X for( i=2; i<ac; i++ ) {
- X if( !(ind=index(av[i],'='))) {
- X ierror( av[i],500);
- X free( tmp );
- X return 20;
- X }
- X *put++=atoi(av[i]);
- X *put++=atoi(ind+1);
- X }
- X
- X for( i=0; i<len; i++ ) {
- X for( get=tmp; get<put; get+=2 )
- X if( *get==map[2*i] )
- X break;
- X if( get==put ) {
- X *put++=map[2*i];
- X *put++=map[2*i+1];
- X }
- X }
- X
- X if( map && map!=DefKeymap0 && map!=DefKeymap1 )
- X free( map );
- X Keymap[n]=tmp;
- X Curmap=0;
- X
- X return 0;
- X}
- X
- Xstatic int
- Xmyget( void )
- X{
- X int c;
- X
- X lasttya=tyahdptr;
- X if( unget )
- X c=unget, unget=0;
- X else if( tyahdptr && *tyahdptr)
- X c=*tyahdptr++;
- X else {
- X#ifndef AZTEC_C
- X fflush(stdout);
- X#endif
- X if( (c=getchar())!=155 )
- X tabctr--, qcdctr--;
- X }
- X
- X return c;
- X}
- X
- Xstatic void
- Xmyunget(int c)
- X{
- X unget=c;
- X}
- X
- Xint
- Xnewwidth( void )
- X{
- X extern struct Window *Win;
- X
- X w_width=80;
- X if( !o_nowindow && Win )
- X w_width=(Win->Width-(Win->BorderLeft+Win->BorderRight))/
- X Win->RPort->TxWidth;
- X if( w_width<1 ) w_width=1; /* crash after resizing was reported */
- X return w_width;
- X}
- X
- X
- X
- X#else
- X
- Xprepscroll(){}
- Xquickscroll(){}
- X
- X#endif
- X
- END_OF_FILE
- if test 18348 -ne `wc -c <'rawcon.c'`; then
- echo shar: \"'rawcon.c'\" unpacked with wrong size!
- fi
- # end of 'rawcon.c'
- fi
- if test -f 'sub.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sub.c'\"
- else
- echo shar: Extracting \"'sub.c'\" \(21464 characters\)
- sed "s/^X//" >'sub.c' <<'END_OF_FILE'
- X
- X/*
- X * SUB.C
- X *
- X * (c)1986 Matthew Dillon 9 October 1986
- X *
- X * Version 2.07M by Steve Drew 10-Sep-87
- X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
- X * Version 5.00L by Urban Mueller 17-Feb-91
- X *
- X */
- X
- X#include "shell.h"
- X#include "proto.h"
- X
- Xstatic void del_history( void );
- Xstatic int dnext( struct DPTR *dp, char **pname, int *stat);
- Xstatic char *svfile( char *s1, char *s2, FIB *fib);
- Xstatic int exall( BPTR lock, char *path );
- Xstatic void quicksort( char **av, int n );
- X
- X
- X#define HM_STR 0 /* various HISTORY retrieval modes */
- X#define HM_REL 1
- X#define HM_ABS 2
- X
- Xvoid
- Xseterr( int err )
- X{
- X static int LastErr;
- X char buf[32], *val;
- X int stat=0;
- X
- X Lastresult=err;
- X
- X if( LastErr!=err ) {
- X LastErr=err;
- X sprintf(buf, "%d", err);
- X set_var(LEVEL_SET, v_lasterr, buf);
- X
- X if( val=get_var(LEVEL_SET, v_stat))
- X stat = atoi(val);
- X if (stat < Lastresult) set_var(LEVEL_SET, v_stat, buf);
- X }
- X}
- X
- X#define ISSPACE(c) ((c)==' ' || (c)==9 || (c)==0xA0)
- X
- Xchar *
- Xnext_word( char *str )
- X{
- X while (*str && ! ISSPACE(*str)) ++str;
- X while (*str && ISSPACE(*str)) ++str;
- X return str;
- X}
- X
- X/*
- X * FREE(ptr) --frees without actually freeing, so the data is still good
- X * immediately after the free.
- X */
- X
- X
- Xvoid
- XFree( void *ptr )
- X{
- X static char *old_ptr;
- X
- X if (old_ptr) free (old_ptr);
- X old_ptr = ptr;
- X}
- X
- X/*
- X * Add new string to history (H_head, H_tail, H_len,
- X * S_histlen
- X */
- X
- Xvoid
- Xadd_history( char *str )
- X{
- X struct HIST *hist;
- X char *get;
- X
- X for( get=str; *get; get++ )
- X if( (*get&127)<' ')
- X *get=' ';
- X
- X if (H_head != NULL && !strcmp(H_head->line, str))
- X return;
- X while (H_len > S_histlen)
- X del_history();
- X hist = (struct HIST *)salloc (sizeof(struct HIST));
- X if (H_head == NULL) {
- X H_head = H_tail = hist;
- X hist->next = NULL;
- X } else {
- X hist->next = H_head;
- X H_head->prev = hist;
- X H_head = hist;
- X }
- X hist->prev = NULL;
- X hist->line = salloc (strlen(str) + 1);
- X strcpy (hist->line, str);
- X ++H_len;
- X}
- X
- Xstatic void
- Xdel_history()
- X{
- X if (H_tail) {
- X --H_len;
- X ++H_tail_base;
- X free (H_tail->line);
- X if (H_tail->prev) {
- X H_tail = H_tail->prev;
- X free (H_tail->next);
- X H_tail->next = NULL;
- X } else {
- X free (H_tail);
- X H_tail = H_head = NULL;
- X }
- X }
- X}
- X
- Xchar *
- Xget_history( char *ptr, int echo )
- X{
- X struct HIST *hist;
- X int len;
- X int mode = HM_REL;
- X int num = 1;
- X char *str=NULL;
- X char *result = NULL;
- X
- X if (ptr[1] >= '0' && ptr[1] <= '9') {
- X mode = HM_ABS;
- X num = atoi(&ptr[1]);
- X goto skip;
- X }
- X switch (ptr[1]) {
- X case '!':
- X break;
- X case '-':
- X num += atoi(&ptr[2]);
- X break;
- X default:
- X mode = HM_STR;
- X str = ptr + 1;
- X break;
- X }
- Xskip:
- X switch (mode) {
- X case HM_STR:
- X len = strlen(str);
- X for (hist = H_head; hist; hist = hist->next) {
- X if (strncmp(hist->line, str, len) == 0 && *hist->line != '!') {
- X result = hist->line;
- X break;
- X }
- X }
- X break;
- X case HM_REL:
- X for (hist = H_head; hist && num--; hist = hist->next);
- X if (hist)
- X result = hist->line;
- X break;
- X case HM_ABS:
- X len = H_tail_base;
- X for (hist = H_tail; hist && len != num; hist = hist->prev, ++len);
- X if (hist)
- X result = hist->line;
- X break;
- X }
- X if( echo )
- X fprintf(stderr, result ? "%s\n" : "History failed\n", result);
- X if( !result ) result="";
- X return result;
- X}
- X
- Xvoid
- Xreplace_head( char *str )
- X{
- X if (str && strlen(str) && H_head) {
- X free (H_head->line);
- X H_head->line = salloc (strlen(str)+1);
- X strcpy (H_head->line, str);
- X }
- X}
- X
- X
- X#if 0
- X#define CDLEN 20
- Xstatic int cd_len=CDLEN, cd_read, cd_write, cd_current;
- Xstatic char *cd_hist[CDLEN];
- X
- Xadd_cdhist( char *str )
- X{
- X if( !str )
- X return;
- X if( cd_hist[cd_write] )
- X free(cd_hist[cd_write]);
- X cd_hist[cd_write++]=str;
- X cd_write%=cd_len;
- X cd_current=cd_write;
- X}
- X
- Xchar *
- Xback_cdhist( void )
- X{
- X if( cd_current!=cd_write ) cd_current= --cd_current % cd_len;
- X return cd_hist[cd_current];
- X}
- X
- Xchar *
- Xforw_cdhist( void )
- X{
- X if( cd_current!=cd_read ) cd_current= ++cd_current % cd_len;
- X return cd_hist[cd_current];
- X}
- X#endif
- X
- Xvoid
- XpError(char *str )
- X{
- X int ierr = (long)IoErr();
- X ierror(str, ierr);
- X}
- X
- Xierror( char *str, int err )
- X{
- X struct PERROR *per = Perror;
- X
- X setioerror(err);
- X
- X if (err) {
- X for (; per->errstr; ++per) {
- X if (per->errnum == err) {
- X fprintf (stderr, "%s%s%s\n",
- X per->errstr,
- X (str) ? ": " : "",
- X (str) ? str : "");
- X return err;
- X }
- X }
- X fprintf (stderr, "Unknown DOS error %d: %s\n", err, (str) ? str : "");
- X }
- X return err;
- X}
- X
- Xvoid
- Xsetioerror( int err )
- X{
- X static int LastIoError=-1;
- X char buf[20];
- X
- X IoError=err;
- X if( IoError<0 ) IoError=0;
- X if( LastIoError!=IoError) {
- X LastIoError=IoError;
- X sprintf(buf, "%d", IoError);
- X set_var(LEVEL_SET, v_ioerr, buf);
- X }
- X}
- X
- Xchar *
- Xioerror(int num)
- X{
- X struct PERROR *per = Perror;
- X
- X for ( ; per->errstr; ++per)
- X if (per->errnum == num)
- X return per->errstr;
- X return NULL;
- X}
- X
- X/*
- X * Disk directory routines
- X *
- X * dptr = dopen(name, stat)
- X * struct DPTR *dptr;
- X * char *name;
- X * int *stat;
- X *
- X * dnext(dptr, name, stat)
- X * struct DPTR *dptr;
- X * char **name;
- X * int *stat;
- X *
- X * dclose(dptr) -may be called with NULL without harm
- X *
- X * dopen() returns a struct DPTR, or NULL if the given file does not
- X * exist. stat will be set to 1 if the file is a directory. If the
- X * name is "", then the current directory is openned.
- X *
- X * dnext() returns 1 until there are no more entries. The **name and
- X * *stat are set. *stat != 0 if the file is a directory.
- X *
- X * dclose() closes a directory channel.
- X *
- X */
- X
- Xstruct DPTR *
- Xdopen( char *name, int *stat)
- X{
- X struct DPTR *dp;
- X
- X IoError=0;
- X *stat = 0;
- X dp = (struct DPTR *)salloc(sizeof(struct DPTR));
- X if (*name == '\0')
- X dp->lock = DupLock(Myprocess->pr_CurrentDir);
- X else
- X dp->lock = Lock (name,ACCESS_READ);
- X if (dp->lock == NULL) {
- X IoError=IoErr();
- X free (dp);
- X return NULL;
- X }
- X dp->fib = (FIB *)SAllocMem((long)sizeof(FIB), MEMF_PUBLIC);
- X if (!Examine (dp->lock, dp->fib)) {
- X pError (name);
- X dclose (dp);
- X return NULL;
- X }
- X if (dp->fib->fib_DirEntryType >= 0) *stat = 1;
- X return dp;
- X}
- X
- Xstatic int
- Xdnext( struct DPTR *dp, char **pname, int *stat)
- X{
- X if (dp == NULL) return (0);
- X
- X if (ExNext (dp->lock, dp->fib)) {
- X *stat = 0;
- X if( dp->fib->fib_DirEntryType >= 0)
- X *stat= dp->fib->fib_DirEntryType!=ST_USERDIR ? 2 : 1;
- X *pname = dp->fib->fib_FileName;
- X return 1;
- X }
- X return 0;
- X}
- X
- Xint
- Xdclose( struct DPTR *dp )
- X{
- X if (dp == NULL)
- X return 1;
- X if (dp->fib)
- X FreeMem (dp->fib,(long)sizeof(*dp->fib));
- X if (dp->lock)
- X UnLock (dp->lock);
- X free (dp);
- X return 1;
- X}
- X
- X
- Xint
- Xisdir( char *file )
- X{
- X struct DPTR *dp;
- X int stat;
- X
- X stat = 0;
- X if (dp = dopen (file, &stat))
- X dclose(dp);
- X return (stat!=0);
- X}
- X
- X
- Xvoid
- Xfree_expand( char **av )
- X{
- X char **get = av;
- X
- X if (av) {
- X while (*get)
- X free (*get++-sizeof(struct file_info));
- X free (av);
- X }
- X}
- X
- X/*
- X * EXPAND(base,pac)
- X * base - char * (example: "df0:*.c")
- X * pac - int * will be set to # of arguments.
- X *
- X * 22-May-87 SJD. Heavily modified to allow recursive wild carding and
- X * simple directory/file lookups. Returns a pointer to
- X * an array of pointers that contains the full file spec
- X * eg. 'df0:c/sear*' would result in : 'df0:C/Search'
- X *
- X * Now no longer necessary to Examine the files a second time
- X * in do_dir since expand will return the full file info
- X * appended to the file name. Set by formatfile().
- X * eg. fullfilename'\0'rwed NNNNNN NNNN DD-MMM-YY HH:MM:SS
- X *
- X * Caller must call free_expand when done with the array.
- X *
- X * base bname = ename =
- X * ------ ------- -------
- X * "*" "" "*"
- X * "!*.info" "" "*.info" (wild_exclude set)
- X * "su*d/*" "" "*" (tail set)
- X * "file.*" "" "file.*"
- X * "df0:c/*" "df0:c" "*"
- X * "" "" "*"
- X * "df0:.../*" "df0:" "*" (recur set)
- X * "df0:sub/.../*" "df0:sub" "*" (recur set)
- X *
- X * ---the above base would be provided by execom.c or do_dir().
- X * ---the below base would only be called from do_dir().
- X *
- X * "file.c" "file.c" "" if (dp == 0) fail else get file.c
- X * "df0:" "df0:" "*"
- X * "file/file" "file/file" "" (dp == 0) so fail
- X * "df0:.../" "df0:" "*" (recur set)
- X *
- X */
- X
- Xchar **
- Xexpand( char *base, int *pac )
- X{
- X char *ptr;
- X char **eav = (char **)salloc(sizeof(char *) * (2));
- X short eleft, eac;
- X char *name;
- X char *bname, *ename, *tail;
- X int stat, recur, scr, bl;
- X struct DPTR *dp;
- X
- X IoError = *pac = recur = eleft = eac = 0;
- X
- X base = strcpy(malloc(strlen(base)+1), base);
- X for (ptr = base; *ptr && *ptr != '?' && *ptr != '*'; ++ptr);
- X
- X if (!*ptr) /* no wild cards */
- X --ptr;
- X else
- X for (; ptr >= base && !(*ptr == '/' || *ptr == ':'); --ptr);
- X
- X if (ptr < base) {
- X bname = strcpy (malloc(1), "");
- X } else {
- X scr = ptr[1];
- X ptr[1] = '\0';
- X if (!strcmp(ptr-3,".../")) {
- X recur = 1;
- X *(ptr-3) = '\0';
- X }
- X bname = strcpy (salloc(strlen(base)+2), base);
- X ptr[1] = scr;
- X }
- X bl = strlen(bname);
- X ename = ++ptr;
- X for (; *ptr && *ptr != '/'; ++ptr);
- X scr = *ptr;
- X *ptr = '\0';
- X if (scr) ++ptr;
- X tail = ptr;
- X
- X if ((dp = dopen (bname, &stat)) == NULL || (stat == 0 && *ename)) {
- X free (bname);
- X free (base);
- X free (eav);
- X return (NULL);
- X }
- X
- X if (!stat) { /* eg. 'dir file' */
- X char *p,*s;
- X for(s = p = bname; *p; ++p) if (*p == '/' || *p == ':') s = p;
- X if (s != bname) ++s;
- X *s ='\0';
- X eav[eac++] = svfile(bname,dp->fib->fib_FileName,dp->fib);
- X goto done;
- X }
- X if (!*ename) ename = "*"; /* eg. dir df0: */
- X if (*bname && bname[bl-1] != ':' && bname[bl-1] != '/') { /* dir df0:c */
- X bname[bl] = '/';
- X bname[++bl] = '\0';
- X }
- X while ((dnext (dp, &name, &stat)) && !breakcheck()) {
- X int match = compare_ok(ename,name,0);
- X if (match && (recur || !*tail)) {
- X if (eleft < 2) {
- X char **scrav = (char **)salloc(sizeof(char *) * (eac + 10));
- X memmove (scrav, eav, (eac + 1) << 2);
- X free (eav);
- X eav = scrav;
- X eleft = 10;
- X }
- X eav[eac++] = svfile(bname,name,dp->fib);
- X --eleft;
- X }
- X if ((*tail && match) || recur) {
- X int alt_ac;
- X char *search, **alt_av, **scrav;
- X BPTR lock;
- X
- X if (stat!=1) /* expect more dirs, but this not a dir */
- X continue;
- X lock = CurrentDir (dp->lock);
- X search = salloc(strlen(ename)+strlen(name)+strlen(tail)+6);
- X strcpy (search, name);
- X strcat (search, "/");
- X if (recur) {
- X strcat(search, ".../");
- X strcat(search, ename);
- X }
- X strcat (search, tail);
- X scrav = alt_av = expand (search, &alt_ac);
- X free(search);
- X CurrentDir (lock);
- X if (scrav) {
- X while (*scrav) {
- X int l;
- X if (eleft < 2) {
- X char **scrav = (char **)salloc(sizeof(char *)*(eac+10));
- X memmove ( scrav, eav, (eac + 1) << 2);
- X free (eav);
- X eav = scrav;
- X eleft = 10;
- X }
- X
- X l = strlen(*scrav);
- X eav[eac] = salloc(bl+l+1+sizeof(struct file_info));
- X memcpy( eav[eac], *scrav-sizeof(struct file_info),
- X sizeof(struct file_info));
- X eav[eac]+=sizeof(struct file_info);
- X strcpy( eav[eac], bname);
- X strcat( eav[eac], *scrav);
- X
- X free (*scrav-sizeof(struct file_info));
- X ++scrav;
- X --eleft, ++eac;
- X }
- X free (alt_av);
- X }
- X }
- X }
- Xdone:
- X dclose (dp);
- X *pac = eac;
- X eav[eac] = NULL;
- X free (bname);
- X free (base);
- X if (eac)
- X return (eav);
- X free (eav);
- X return (NULL);
- X}
- X
- Xchar *
- Xstrupr( char *s )
- X{
- X char *old=s;
- X while (*s) *s=toupper(*s), s++;
- X return old;
- X}
- X
- Xchar *
- Xstrlwr( char *s )
- X{
- X char *old=s;
- X while (*s) *s=tolower(*s), s++;
- X return old;
- X}
- X
- X/*
- X * Compare a wild card name with a normal name
- X */
- X
- Xint
- Xcompare_ok( char *wild, char *name, int casedep)
- X{
- X int queryflag;
- X char buf[260], wildbuf[260], *lowname;
- X
- X if (queryflag=(*wild=='&')) wild++;
- X if (*wild=='!') *wild='~';
- X
- X if (! casedep) {
- X strupr(wild);
- X strcpy(buf,name);
- X strupr(buf);
- X lowname=buf;
- X } else
- X lowname=name;
- X
- X PreParse(wild, wildbuf);
- X if ( ! PatternMatch(wildbuf,lowname)) return 0;
- X
- X if (queryflag) {
- X printf("Select %s%-16s%s [y/n] ? ",o_hilite,name,o_lolite);
- X gets(buf);
- X return (toupper(*buf)=='Y');
- X }
- X return 1;
- X}
- X
- Xstatic char *
- Xsvfile( char *s1, char *s2, FIB *fib)
- X{
- X int len=strlen(s1)+strlen(s2)+1;
- X char *p = salloc (len+sizeof(struct file_info));
- X struct file_info *info;
- X
- X info=(struct file_info *)p;
- X p+=sizeof(struct file_info);
- X strcpy(p, s1);
- X strcat(p, s2);
- X info->flags = fib->fib_Protection;
- X if( fib->fib_DirEntryType<0 ) {
- X info->size = fib->fib_Size;
- X info->blocks= fib->fib_NumBlocks;
- X } else {
- X info->size = -1;
- X info->blocks= 0;
- X }
- X if( fib->fib_Comment[0] )
- X info->flags|= 1<<30;
- X info->date=fib->fib_Date;
- X info->class[0]=1;
- X return p;
- X}
- X
- X
- X
- Xstatic FILE *out;
- Xstatic int NumDirs;
- X
- Xvoid
- Xexpand_all( char *name, FILE *file )
- X{
- X BPTR lock;
- X char path[300];
- X FIB *fib;
- X
- X out=file;
- X printf( " %s\n", name );
- X NumDirs=0;
- X
- X if(fib=AllocMem(sizeof(struct FileInfoBlock),0)) {
- X if( lock=Lock( name, ACCESS_READ )) {
- X strcpy( path, name );
- X exall( lock, path );
- X printf( "\n", NumDirs );
- X }
- X FreeMem(fib,sizeof(struct FileInfoBlock));
- X }
- X}
- X
- Xstatic int
- Xexall( BPTR lock, char *path )
- X{
- X BPTR old, sublock;
- X int len;
- X struct FileInfoBlock *fib;
- X
- X old=CurrentDir( lock );
- X
- X if( !(fib=AllocMem(sizeof(struct FileInfoBlock),0)) )
- X return 1;
- X
- X len=strlen( path );
- X Examine( lock, fib );
- X while( ExNext( lock, fib ) ) {
- X if( fib->fib_DirEntryType==ST_USERDIR )
- X if( sublock=Lock( fib->fib_FileName, ACCESS_READ )) {
- X if( !len || path[len-1]==':' )
- X sprintf(path+len,"%s", fib->fib_FileName);
- X else
- X sprintf(path+len,"/%s", fib->fib_FileName);
- X fprintf( out, "%s\n", path );
- X fprintf( stdout, " Directories: %d\015", ++NumDirs );
- X fflush ( stdout );
- X if(exall( sublock, path ))
- X break;
- X path[len]=0;
- X }
- X }
- X FreeMem( fib, sizeof(struct FileInfoBlock));
- X CurrentDir( old );
- X return dobreak();
- X}
- X
- X
- X
- X/* Sort routines */
- X
- Xstatic int reverse, factor;
- X
- Xint
- Xcmp( FILEINFO *s1, FILEINFO *s2)
- X{
- X return Strcmp( (char *)(s1+1), (char *)(s2+1) );
- X}
- X
- Xint
- Xsizecmp( FILEINFO *s1, FILEINFO *s2)
- X{
- X return s2->size - s1->size;
- X}
- X
- Xint
- Xdatecmp( FILEINFO *s1, FILEINFO *s2 )
- X{
- X int r;
- X struct DateStamp *d1=&s1->date, *d2=&s2->date;
- X if( !(r= d2->ds_Days - d1->ds_Days))
- X if( !(r=d2->ds_Minute - d1->ds_Minute ) )
- X r=d2->ds_Tick - d1->ds_Tick;
- X return r;
- X}
- X
- X
- Xint
- Xnumcmp( FILEINFO *s1, FILEINFO *s2 )
- X{
- X return atoi((char *)(s1+1))-atoi((char *)(s2+1));
- X}
- X
- Xstatic void
- Xenterclass( FILEINFO *info )
- X{
- X char *class, *iclass=info->class, *t;
- X
- X if( *iclass==1 ) {
- X if( class=getclass( (char *)(info+1))) {
- X strncpy( iclass, class, 11 );
- X iclass[11]=0;
- X if( t=index(iclass,0xA0))
- X *t=0;
- X } else
- X iclass[0]=0;
- X }
- X}
- X
- Xint
- Xclasscmp( FILEINFO *info1, FILEINFO *info2 )
- X{
- X int r;
- X
- X enterclass( info1 );
- X enterclass( info2 );
- X
- X r= Strcmp( info1->class, info2->class );
- X if( !r ) r=Strcmp((char *)(info1+1),(char *)(info2+1));
- X return r;
- X}
- X
- X
- Xvoid
- XQuickSort( char *av[], int n)
- X{
- X reverse=factor=0;
- X DirQuickSort( av, n, cmp, 0, 0 );
- X}
- X
- Xstatic int (*compare)(FILEINFO *, FILEINFO *);
- X
- Xvoid
- XDirQuickSort( char *av[], int n, int (*func)(FILEINFO *,FILEINFO *), int rev, int fac)
- X{
- X reverse=rev; compare=func; factor=fac;
- X quicksort( av, n-1 );
- X}
- X
- Xstatic int
- Xdocompare(char *s1,char *s2)
- X{
- X FILEINFO *i1=(FILEINFO *)s1-1, *i2=(FILEINFO *)s2-1;
- X int r=(*compare)( i1,i2 );
- X
- X if( reverse ) r =-r;
- X if( factor ) r+= factor*((i2->size<0) - (i1->size<0));
- X return r;
- X}
- X
- X
- Xstatic void
- Xquicksort( char **av, int n )
- X{
- X char **i, **j, *x, *t;
- X
- X
- X if( n>0 ) {
- X i=av; j=av+n; x=av[ n>>1 ];
- X do {
- X while( docompare(*i,x)<0 ) i++;
- X while( docompare(x,*j)<0 ) --j;
- X if( i<=j )
- X { t=*i; *i=*j; *j=t; i++; j--; }
- X } while( i<=j );
- X
- X if( j-av < av+n-i ) {
- X quicksort( av, j-av );
- X quicksort( i , av+n-i);
- X } else {
- X quicksort( i , av+n-i);
- X quicksort( av, j-av );
- X }
- X }
- X}
- X
- X
- Xint
- Xfilesize( char *name )
- X{
- X BPTR lock;
- X struct FileInfoBlock *fib;
- X int len=0;
- X
- X if( lock = Lock (name,ACCESS_READ)) {
- X if( fib=(struct FileInfoBlock *)AllocMem(sizeof(*fib),MEMF_PUBLIC)) {
- X if (Examine (lock, fib))
- X len=fib->fib_Size;
- X FreeMem( fib, sizeof(*fib));
- X }
- X UnLock(lock);
- X }
- X return len;
- X}
- X
- X
- X#ifndef MIN
- X#define MIN(x,y) ((x)<(y)?(x):(y))
- X#endif
- X
- Xchar **
- Xand( char **av1, int ac1, char **av2, int ac2, int *ac, int base )
- X{
- X char **av=(char **)salloc(MIN(ac1,ac2)*sizeof(char *) ), *str;
- X int i, j, k=0;
- X
- X for( i=0; i<ac1; i++ )
- X for( j=0, str=base ? BaseName(av1[i]) : av1[i]; j<ac2; j++ )
- X if( !Strcmp(str, base ? BaseName(av2[j]) : av2[j]))
- X av[k++]=av1[i];
- X *ac=k;
- X return av;
- X}
- X
- Xchar **
- Xwithout( char **av1, int ac1, char **av2, int ac2, int *ac, int base )
- X{
- X char **av=(char **)salloc(ac1*sizeof(char *) ), *str;
- X int i, j, k=0;
- X
- X for( i=0; i<ac1; i++ ) {
- X for( j=0, str=base ? BaseName(av1[i]) : av1[i]; j<ac2; j++ )
- X if( !Strcmp(str, base ? BaseName(av2[j]) : av2[j] ) )
- X break;
- X if( j==ac2 )
- X av[k++]=av1[i];
- X }
- X *ac=k;
- X return av;
- X}
- X
- Xchar **
- Xor( char **av1, int ac1, char **av2, int ac2, int *ac, int base )
- X{
- X char **av=(char **)salloc((ac1+ac2)*sizeof(char *) ), *str;
- X int i, j, k=0;
- X
- X for( i=0; i<ac1; i++ )
- X av[k++]=av1[i];
- X
- X for( i=0; i<ac2; i++ ) {
- X for( j=0, str=base ? BaseName(av2[i]) : av2[i]; j<ac1; j++ )
- X if( !Strcmp(str, base ? BaseName(av1[j]) : av1[j] ) )
- X break;
- X if( j==ac1 )
- X av[k++]=av2[i];
- X }
- X
- X *ac=k;
- X return av;
- X}
- X
- Xvoid
- Xclear_archive_bit( char *name )
- X{
- X struct DPTR *dp;
- X int stat;
- X
- X if(dp = dopen(name,&stat) ) {
- X SetProtection( name, dp->fib->fib_Protection&~FIBF_ARCHIVE);
- X dclose( dp );
- X }
- X}
- X
- Xchar *
- Xitoa( int i )
- X{
- X static char buf[20];
- X char *pos=buf+19;
- X int count=4, flag=0;
- X
- X if( i<0 )
- X flag=1, i=-i;
- X
- X do {
- X if( !--count )
- X count=3, *--pos=',';
- X *--pos= i%10+'0';
- X } while( i/=10 );
- X
- X if( flag )
- X *--pos='-';
- X
- X return pos;
- X}
- X
- Xchar *
- Xitok( int i )
- X{
- X static char buf[16], which;
- X char *exp=" KMG", *ptr= buf+(which=8-which);
- X
- X do
- X i=(i+512)/1024, exp++;
- X while( i>1024 );
- X sprintf( ptr,"%d%c",i,*exp);
- X
- X return ptr;
- X}
- X
- Xchar *
- Xnext_a0( char *str )
- X{
- X while( *str && *str!=0xA0 && *str!='=' && *str!=',') str++;
- X return *str ? str+1 : NULL;
- X}
- X
- Xstatic int
- Xgethex( char *str, int l )
- X{
- X int i, val=0, n, c;
- X
- X if( *str=='.' ) return l==2 ? 256 : 0;
- X
- X for( i=0; i<l || !l; i++ ) {
- X c=*str++;
- X if ( c>='0' && c<='9' ) n=c-'0';
- X else if( c>='a' && c<='f' ) n=c-'a'+10;
- X else if( c>='A' && c<='F' ) n=c-'A'+10;
- X else break;;
- X val=16*val+n;
- X }
- X return (l && i!=l) ? -1 : val;
- X}
- X
- Xstrwrdcmp( char *str, char *wrd )
- X{
- X int ret;
- X char *ind=index(wrd,0xA0);
- X
- X if( ind ) *ind=0;
- X ret=compare_ok(wrd,str,0);
- X if( ind ) *ind=0xA0;
- X return !ret;
- X}
- X
- Xint
- Xwrdlen( char *str )
- X{
- X char *old=str;
- X
- X while( *str && *str!=0xA0 ) str++;
- X return str-old;
- X}
- X
- Xchar *classfile;
- X
- Xchar *
- Xgetclass(char *file)
- X{
- X CLASS *cl;
- X char *class, *str, *arg, *get, *buf;
- X int offs, byte, len, fail;
- X BPTR fh;
- X
- X if( classfile ) {
- X char buf[80];
- X sprintf(buf,"source %s",classfile);
- X execute(buf);
- X classfile=0;
- X }
- X
- X if( isdir(file) ) return "dir";
- X
- X if( !(buf=calloc(1024,1))) return NULL;
- X if( !(fh=Open(file,MODE_OLDFILE))) return NULL;
- X len=Read( fh,buf,1023);
- X Close(fh);
- X
- X for( cl=CRoot; cl; cl=cl->next ) {
- X class=cl->name;
- X if(!(str=next_a0(cl->name))) continue;
- X while( str ) {
- X if(!(arg=next_a0( str ))) goto nextclass;
- X switch( *str ) {
- X case 's':
- X if( (offs=strlen(file)-wrdlen(arg))<0 ) break;
- X if( !strwrdcmp(file+offs,arg)) goto found;
- X break;
- X case 'n':
- X if( !strwrdcmp(BaseName(file),arg) ) goto found;
- X break;
- X case 'd':
- X goto found;
- X case 'o':
- X offs=gethex(arg,0);
- X if( !(arg=index(arg,','))) goto nextclass;
- X if( offs>len-10 ) break;
- X for( get=buf+offs, ++arg; (byte=gethex(arg,2))>=0; arg+=2 )
- X if( *get++!=byte && byte!=256 )
- X goto nexttry;
- X goto found;
- X case 'c':
- X if( !len )
- X goto nexttry;
- X for( get=buf, fail=0; get<buf+len; get++ )
- X if( *get<9 || *get>13 && *get<32 || *get>127 )
- X fail++;
- X if( fail*8>len )
- X goto nexttry;
- X goto found;
- X case 'a':
- X goto nextclass;
- X default:
- X goto nextclass;
- X }
- Xnexttry: str=next_a0(arg);
- X }
- Xnextclass: ;
- X }
- X
- X free(buf);
- X return NULL;
- X
- Xfound:
- X free(buf);
- X return class;
- X}
- X
- Xchar *
- Xgetaction( char *class, char *action )
- X{
- X CLASS *cl;
- X char *cur, *ind;
- X int len;
- X
- X for( len=0; class[len] && class[len]!=0xA0; len++ ) ;
- X for( cl=CRoot; cl; cl=cl->next ) {
- X if( strncmp( cur=cl->name,class,len+1 ))
- X continue;
- X do
- X cur=index( cur,0xA0 );
- X while( cur && *++cur!='a');
- X
- X if( cur && (cur=index( ++cur,0xA0 ))) {
- X do {
- X if( !(ind=index( ++cur,'=' )))
- X return NULL;
- X len=ind-cur;
- X if( len==strlen(action) && !strncmp(action,cur,len))
- X return ++ind;
- X } while( cur=index(cur,0xA0) );
- X }
- X }
- X return NULL;
- X}
- X
- Xint
- Xdoaction( char *file, char *action, char *args )
- X{
- X char *class, *com, *c, *copy, *spc=index(file,' ');
- X
- X if( !(class=getclass(file)))
- X return 10;
- X if( !(com=getaction(class,action)))
- X return 11;
- X if( c=index(com,0xA0) )
- X *c=0;
- X copy=salloc( strlen(com)+strlen(file)+strlen(args)+7 );
- X sprintf(copy,spc?"%s \"%s\" %s":"%s %s %s", com, file, args);
- X execute(copy);
- X free(copy);
- X if( c )
- X *c=0xA0;
- X return 0;
- X}
- X
- Xvoid *
- Xsalloc( int len )
- X{
- X void *ret;
- X
- X if( !len ) len++;
- X
- X if( !(ret=malloc(len))) {
- X fprintf(stderr,"Out of memory -- exiting\n");
- X main_exit( 20 );
- X }
- X return ret;
- X}
- X
- Xvoid *
- XSAllocMem( long size, long req )
- X{
- X void *ret;
- X
- X if( !(ret=AllocMem(size,req))) {
- X fprintf(stderr,"Out of memory -- exiting\n");
- X main_exit( 20 );
- X }
- X return ret;
- X}
- END_OF_FILE
- if test 21464 -ne `wc -c <'sub.c'`; then
- echo shar: \"'sub.c'\" unpacked with wrong size!
- fi
- # end of 'sub.c'
- fi
- echo shar: End of archive 2 \(of 6\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 3 4 5 6 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 6 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
- Mail comments to the moderator at <amiga-request@uunet.uu.net>.
- Post requests for sources, and general discussion to comp.sys.amiga.misc.
-